package io.feige.rpc.consumer.cluster.implement;

import io.feige.rpc.consumer.RpcConsumerService;
import io.feige.rpc.consumer.cluster.LoadBalance;
import io.feige.rpc.consumer.config.ServiceSocketAddress;
import io.feige.rpc.exception.NoAvailableProviderException;

import java.util.ArrayList;
import java.util.List;

public class DefaultLoadBalanceImpl implements LoadBalance {

	private int seq=0;
	
	private RpcConsumerService rpcConsumerService;
	
	public DefaultLoadBalanceImpl(RpcConsumerService rpcConsumerService){
		this.rpcConsumerService=rpcConsumerService;
	}
	
	@Override
	public ServiceSocketAddress select(List<ServiceSocketAddress> socketAddresses) {
		if (socketAddresses.size()==0) {
			return null;
		}
		
		if (seq==Integer.MAX_VALUE) {
			seq=0;
		}
		
		List<ServiceSocketAddress> availableAddresses=new ArrayList<ServiceSocketAddress>();
		for (ServiceSocketAddress serviceSocketAddress : socketAddresses) {
			if (rpcConsumerService.getConnectionService().checkConnection(serviceSocketAddress)) {
				if(serviceSocketAddress.getWeight()>0){
					for (int i = 0; i < serviceSocketAddress.getWeight(); i++) {
						availableAddresses.add(serviceSocketAddress);
					}
				}else{
					availableAddresses.add(serviceSocketAddress);
				}
				
			}
		}
		if (availableAddresses.size()==0) {
			throw new NoAvailableProviderException(); 
		}
		ServiceSocketAddress address=availableAddresses.get(seq++%availableAddresses.size());
		return address;
	}

}
